import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;

import javax.swing.AbstractAction;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.WindowConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import javazoom.jlgui.basicplayer.BasicPlayer;
import javazoom.jlgui.basicplayer.BasicPlayerException;

public class Main {
	
	/*
	 * My global variables. I use booleans to control the state of the song so that the program
	 * knows when the song is paused and when it is currently playing. I use the same BasicPlayer
	 * and CurrentListener for all methods to help simplify the program.
	 */
	
	public static boolean songPlaying = false;
	public static boolean songPaused = false;
	public static BasicPlayer player = new BasicPlayer();
	public static CurrentListener nowPlaying = new CurrentListener();
	public static Playlist userPlaylist = new Playlist();
	public static DefaultListModel<String> listOfSongs = new DefaultListModel<String>();
	public static JList<String> songList = new JList<String>(listOfSongs);
	public static int currentIndex = -1;
	public static final int MAX_VOLUME = 100;
	public static final int MIN_VOLUME = 0;
	public static final int DEFAULT_VOLUME = 30;
	
	/*
	 * Main method, drives the program
	 */
	
	public static void main (String Args[]) {
		createScreen();
	}
	
	/*
	 * Creates the graphical user interface
	 */
	
	private static void createScreen () {
		JLabel sliderLabel = new JLabel("Volume", JLabel.CENTER);
		JLabel nameLabel = new JLabel("Created by Kameron Kemnitz for CS 680");
		nameLabel.setFont(new Font("Times New Roman",Font.BOLD,16));
		//sliderLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
		JButton playButton = createPlayButton();
		JButton pauseButton = createPauseButton();
		JButton stopButton = createStopButton();
		JButton nextButton = createNextSongButton();
		JButton previousButton = createPreviousSongButton();
		JSlider volumeControl = createVolumeControl();
		//JFrame.setDefaultLookAndFeelDecorated(true);
		JFrame frame = new JFrame("Music Player");
		JPanel panel = new JPanel();
		frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		JMenuBar menu = createMenu();
		frame.setJMenuBar(menu);
		panel.add(playButton);
		playButton.setBounds(300,100, 60, 50);
		panel.add(pauseButton);
		pauseButton.setBounds(300,100,50,40);
		panel.add(stopButton);
		stopButton.setBounds(300,100,600,500);
		panel.add(nextButton);
		panel.add(previousButton);
		frame.setBackground(Color.YELLOW);
		frame.add(panel, BorderLayout.PAGE_START);
		frame.add(songList, BorderLayout.CENTER);
		frame.add(volumeControl, BorderLayout.PAGE_END);
		panel.setBackground(Color.YELLOW);
		DefaultListCellRenderer renderer = (DefaultListCellRenderer)songList.getCellRenderer();
		renderer.setHorizontalAlignment(JLabel.CENTER);
		songList.setFont(new Font("Arial",Font.BOLD,14));
		setListAction();
		//frame.add(volumeControl, BorderLayout.SOUTH);
		frame.setIconImage(new ImageIcon("dc86Bdgce.png").getImage());
		frame.setSize(500, 500);
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
	}
	
	/*
	 * Creates the play button
	 */
	
	private static JButton createPlayButton() {
		JButton b1 = new JButton(new AbstractAction("Play") {
			public void actionPerformed(ActionEvent e) {
				/*
				 * If there is currently a song that is paused
				 */
				if ((songPlaying == true) && (songPaused == true)) {
					nowPlaying.resumeSong(player);
					songPaused = false;
				}
				/*
				 * Else, there is no song playing right now at all
				 */
				else if (songPlaying == false) {
					songPlaying = userPlaylist.playFirstSong(nowPlaying, player);
					if (songPlaying == true)
						currentIndex = 0;
				}
			}
		});
		b1.setMnemonic(KeyEvent.VK_D);
		b1.setActionCommand("disable");
		return b1;
	}
	
	/*
	 * Creates the pause button
	 */
	
	private static JButton createPauseButton() {
		JButton b1 = new JButton(new AbstractAction("Pause") {
			public void actionPerformed(ActionEvent e) {
				/*
				 * If there is currently a song playing
				 */
				if (songPlaying == true) {
					nowPlaying.pauseSong(player);
					songPaused = true;
				}
				/*
				 * Else, there is no song playing
				 */
				else if (songPlaying == false) {
					;
				}
			}
		});
		b1.setMnemonic(KeyEvent.VK_D);
		b1.setActionCommand("disable");
		return b1;
	}
	
	/*
	 * Creates the stop button
	 */
	
	private static JButton createStopButton() {
		JButton b1 = new JButton(new AbstractAction("Stop") {
			public void actionPerformed(ActionEvent e) {
				/*
				 * If there is currently a song playing
				 */
				if (songPlaying == true) {
					nowPlaying.stopSong(player);
					songPlaying = false;
					currentIndex = -1;
				}
				/*
				 * Else, there is no song playing
				 */
				else if (songPlaying == false) {
					;
				}
			}
		});
		b1.setMnemonic(KeyEvent.VK_D);
		b1.setActionCommand("disable");
		return b1;
	}
	
	/*
	 * Creates the next button, which skips to the next song in the playlist if one
	 * actually exists.
	 */
	
	private static JButton createNextSongButton() {
		JButton b1 = new JButton(new AbstractAction("Next") {
			public void actionPerformed(ActionEvent e) {
				boolean nextSongExists;
				/*
				 * If there is currently a song playing
				 */
				if (songPlaying == true) {
					nextSongExists = userPlaylist.playNextSong(currentIndex, nowPlaying, player);
					/*
					 * If the next song actually exists
					 */
					if (nextSongExists == true)
						currentIndex++;
				}
			}
		});
		b1.setMnemonic(KeyEvent.VK_D);
		b1.setActionCommand("disable");
		return b1;
	}
	
	/*
	 * Creates the previous button, which skips to the previous song in the playlist if one
	 * actually exists.
	 */
	
	private static JButton createPreviousSongButton() {
		JButton b1 = new JButton(new AbstractAction("Previous") {
			public void actionPerformed(ActionEvent e) {
				boolean previousSongExists;
				/*
				 * If there is currently a song playing
				 */
				if (songPlaying == true) {
					previousSongExists = userPlaylist.playNextSong(currentIndex, nowPlaying, player);
					/*
					 * If the previous song actually exists
					 */
					if (previousSongExists == true)
						currentIndex--;
				}
			}
		});
		b1.setMnemonic(KeyEvent.VK_D);
		b1.setActionCommand("disable");
		return b1;
	}
	
	/*
	 * Creates the volume control slider, which uses the slider to control the volume of
	 * the music that plays.
	 */
	
	private static JSlider createVolumeControl() {
		JSlider s1 = new JSlider(JSlider.HORIZONTAL, MIN_VOLUME, MAX_VOLUME, DEFAULT_VOLUME);
		s1.setMajorTickSpacing(10);
		s1.setMinorTickSpacing(5);
		s1.setPaintLabels(true);
		s1.setPaintTicks(true);
		class SliderListener implements ChangeListener {
			public void stateChanged (ChangeEvent e) {
				JSlider source = (JSlider)e.getSource();
				if (!source.getValueIsAdjusting()) {
					int newVolume = (int)source.getValue();
					double volume = (double) ((double) newVolume / 100);
					try {
						player.setGain(volume);
					} catch (BasicPlayerException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
				}
		}
		s1.addChangeListener(new SliderListener());
		return s1;
	}
	
	/*
	 * Creates the menu for the program
	 */
	
	private static JMenuBar createMenu() {
		JMenuBar menu = new JMenuBar();
		
		JMenu file = new JMenu("File");
		menu.add(file);
		JMenuItem about = new JMenuItem("About");
		file.add(about);
		JMenuItem exit = new JMenuItem(new AbstractAction("Exit") {
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		});
		file.add(exit);
		
		JMenuItem addSong = new JMenuItem(new AbstractAction("Add Song") {
			public void actionPerformed(ActionEvent e) {
				Song newSong = new Song();
				newSong = newSong.createNewSong(createMenu());
				addSong(newSong);
			}
		});
		menu.add(addSong);
		
		return menu;
	}
	
	/*
	 * If a song is double or triple clicked, it will play
	 */
	
	private static void setListAction () {
		songList.addMouseListener(new MouseAdapter() {
			public void mouseClicked (MouseEvent evt) {
				JList list = (JList)evt.getSource();
				if (evt.getClickCount() == 2) {
					int index = list.locationToIndex(evt.getPoint());
					userPlaylist.playSong(index, nowPlaying, player);
					songPlaying = true;
					currentIndex = index;
				} else if (evt.getClickCount() == 3) {
					int index = list.locationToIndex(evt.getPoint());
					userPlaylist.playSong(index, nowPlaying, player);
					songPlaying = true;
					currentIndex = index;
				}
			}
		});
	}
	
	/*
	 * Adds the song to the GUI
	 */
	
	private static void addSong(Song song) {
		String songTitle = song.getSongTitle();
		String fixedSongTitle = song.removeFileExtension(songTitle);
		listOfSongs.addElement(fixedSongTitle);
		userPlaylist.addSong(song);
	}

}
